using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Collections.Specialized;
using System.IO;
using System.Text.RegularExpressions;
using WbsEditor.Properties;

namespace WbsEditor
{
    public partial class MainForm : Form
    {
        public static string VERSION = "3.4.4";
        private string CAPTION = "Work Breakdown Structure Editor v" + VERSION;

        public MainForm()
        {
            _startupXmlFile = null;
            _startupWorkItem = -1;

            InitializeComponent();
            Text = CAPTION + " [(untitled)]";

            LoadRecentWbs();

            ReadUserSettings();
            LoadHelpFile();
        }

        private void LoadHelpFile()
        {
            try
            {
                string startupPath = Application.StartupPath;
                string rtfPath = Path.Combine(startupPath, "WbsEditorHelp.rtf");
                using (StreamReader reader = new StreamReader(rtfPath))
                {
                    string rtf = reader.ReadToEnd();

                    helpText.Rtf = rtf;
                }
            }
            catch (Exception)
            {
                helpText.Text = "(Could not load WbsEditorHelp.rtf)";
            }
        }

        private void ReadUserSettings()
        {
            hideShortcutHelpWindowToolStripMenuItem.Checked = WbsEditor.Properties.Settings.Default.HideShortcutWindow;
            _wbsCanvas.EstimationPercentageDefault = WbsEditor.Properties.Settings.Default.EstimationPercentage;
            _wbsCanvas.Settings.CheckPlausis = WbsEditor.Properties.Settings.Default.CheckPlausis;
            _wbsCanvas.Settings.PrintPlausis = WbsEditor.Properties.Settings.Default.PrintPlausis;
            _wbsCanvas.Settings.ProgressBarColor = WbsEditor.Properties.Settings.Default.ProgressColor;
            _wbsCanvas.Settings.InnerProgressColor = WbsEditor.Properties.Settings.Default.InnerProgressColor;
            _wbsCanvas.Settings.TitleColor = WbsEditor.Properties.Settings.Default.TitleColor;
            _wbsCanvas.Settings.PlausiMarkColor = WbsEditor.Properties.Settings.Default.PlausiMarkColor;
            _wbsCanvas.Settings.FontFamilyName = WbsEditor.Properties.Settings.Default.Font;
            _wbsCanvas.Settings.FindResultColor = WbsEditor.Properties.Settings.Default.FindResultColor;
            try { _wbsCanvas.Settings.RefreshAtLoad = (WbsEditor.WbsSettings.RefreshAtLoadEnum)WbsEditor.Properties.Settings.Default.RefreshAtLoad; }
            catch (Exception) { _wbsCanvas.Settings.RefreshAtLoad = WbsEditor.WbsSettings.RefreshAtLoadEnum.Ask; }
            _wbsCanvas.CurrentWorkItemType = WbsEditor.Properties.Settings.Default.WorkItemType;
            CheckPersistUnit();
        }

        private void CheckPersistUnit()
        {
            if (!WbsEditor.Properties.Settings.Default.HasAskedAboutDefaultPersistanceSetting)
            {
                if (WbsEditor.Properties.Settings.Default.DefaultPersistUnit.Equals("Hours"))
                {
                    WbsEditor.Properties.Settings.Default.HasAskedAboutDefaultPersistanceSetting = true;
                    DialogResult res = MessageBox.Show(this,
                        "You have set 'Hours' as default persistance unit in your work items. Do you want to change this setting to use 'Days' instead?",
                        "Confirm", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
                    if (DialogResult.Yes == res)
                    {
                        WbsEditor.Properties.Settings.Default.DefaultPersistUnit = "Days";
                        _wbsCanvas.WorkBreakdownStructure.PersistUnit = WorkBreakdownStructure.TimeUnit.Days;
                    }
                }
            }
        }

        private void MainForm_Shown(object sender, EventArgs e)
        {
            CheckStartupParameters();
        }

        private void CheckStartupParameters()
        {
            if (!string.IsNullOrEmpty(StartupXmlFile))
            {
                LoadStartupXmlFile();
            }
            else if (StartupWorkItem > 0)
            {
                LoadStartupWorkItem();
            }
        }

        private void LoadStartupXmlFile()
        {
            if (_wbsCanvas.LoadXml(StartupXmlFile))
            {
                SetFileNameInTitle();
            }
        }

        private void LoadStartupWorkItem()
        {
            if (_wbsCanvas.LoadFromWorkItem(StartupWorkItem))
            {
                SetFileNameInTitle();
            }
        }

        private string _startupXmlFile;
        public string StartupXmlFile
        {
            get { return _startupXmlFile; }
            set { _startupXmlFile = value; }
        }

        private int _startupWorkItem;
        public int StartupWorkItem
        {
            get { return _startupWorkItem; }
            set { _startupWorkItem = value; }
        }

        private void LoadRecentWbs()
        {
            string[] locations;
            if (null != WbsEditor.Properties.Settings.Default.RecentWbs)
            {
                locations = new string[WbsEditor.Properties.Settings.Default.RecentWbs.Count];
                for (int i = 0; i < WbsEditor.Properties.Settings.Default.RecentWbs.Count; ++i)
                    locations[i] = WbsEditor.Properties.Settings.Default.RecentWbs[i];
            }
            else
            {
                locations = new string[] { };
            }

            var items = _recentWbsMenuItem.DropDownItems;
            int maxRecentCount = items.Count;
            int count = locations.Length;
            if (count > maxRecentCount)
                count = maxRecentCount;
            for (int i = 0; i < count; ++i)
            {
                string title = "";
                string path = "";
                if (SplitLocation(locations[i], ref title, ref path))
                {
                    items[i].Text = string.Format("&{0} {1} ({2})",
                        i + 1,
                        title,
                        path);
                    items[i].Visible = true;
                    items[i].Tag = string.Format("{0}\";\"{1}", title, path);
                }
            }
            for (int i = count; i < maxRecentCount; ++i)
            {
                items[i].Visible = false;
                items[i].Tag = null;
                items[i].Text = "asfdfg";
            }
            if (count > 0)
                _recentWbsMenuItem.Enabled = true;
            else
                _recentWbsMenuItem.Enabled = false;
        }

        private bool SplitLocation(string loc, ref string title, ref string path)
        {
            int indexOfSplit = loc.IndexOf("\";\"");
            if (indexOfSplit < 0)
                return false;

            title = loc.Substring(0, indexOfSplit);
            path = loc.Substring(indexOfSplit + 3);

            return true;
        }

        private void UpdateRecentFiles(string title, string path)
        {
            var items = _recentWbsMenuItem.DropDownItems;
            var newList = new List<ToolStripDropDownItem>();
            
            int maxRecentCount = items.Count;
            int indexOfPath = -1;
            for (int i = 0; (i < maxRecentCount) && (indexOfPath < 0); ++i)
            {
                if (null != items[i].Tag)
                {
                    string tagString = (string)items[i].Tag;
                    string otherTitle = "";
                    string otherPath = "";
                    SplitLocation(tagString, ref otherTitle, ref otherPath);
                    if (otherPath == path)
                        indexOfPath = i;
                }
            }

            if (indexOfPath == 0)
                return;
            else if (indexOfPath > 0)
            {
                for (int i = indexOfPath; i >= 1; --i)
                {
                    items[i].Tag = items[i - 1].Tag;
                    items[i].Text = BuildTextForItem(i, items[i - 1].Text);
                }
            }
            else
            {
                for (int i = maxRecentCount-1; i >= 1; --i)
                {
                    items[i].Tag = items[i - 1].Tag;
                    items[i].Text = BuildTextForItem(i, items[i - 1].Text);
                }
            }
            items[0].Tag = string.Format("{0}\";\"{1}", title, path);
            items[0].Text = string.Format("&1 {0} ({1})", title, path);

            for (int i = 0; i < maxRecentCount; ++i)
            {
                if (null != items[i].Tag)
                {
                    items[i].Visible = true;
                }
                else
                {
                    items[i].Visible = false;
                }
            }

            _recentWbsMenuItem.Enabled = true;
        }

        private string BuildTextForItem(int index, string oldText)
        {
            var sb = new StringBuilder();
            sb.Append('&');
            sb.Append((index + 1).ToString(CultureInfo.InvariantCulture) + " ");
            
            if (!string.IsNullOrWhiteSpace(oldText))
            {
                int firstIndexAfterBlank = oldText.IndexOf(" ", StringComparison.Ordinal) + 1;
                sb.Append(oldText.Substring(firstIndexAfterBlank, oldText.Length - firstIndexAfterBlank));
            }
            return sb.ToString();
        }

        private void SetFileNameInTitle()
        {
            string text = "";
            string path = "";
            if (!_wbsCanvas.Root.IsPublished)
            {
                if (!string.IsNullOrEmpty(_wbsCanvas.WorkBreakdownStructure.FileName))
                {
                    text = CAPTION + " [" + _wbsCanvas.WorkBreakdownStructure.Title + " - " + _wbsCanvas.WorkBreakdownStructure.FileName;
                    path = _wbsCanvas.WorkBreakdownStructure.FileName;
                }
                else
                {
                    text = CAPTION + " [" + _wbsCanvas.WorkBreakdownStructure.Title;
                }
            }
            else
            {
                text = CAPTION + " [" + _wbsCanvas.WorkBreakdownStructure.Title + " - Work Item #" + _wbsCanvas.Root.WorkItemId;
                path = string.Format("#{0}", _wbsCanvas.Root.WorkItemId);
            }
            if (_wbsCanvas.WorkBreakdownStructure.IsDirty)
                text += "*";
            text += "]";
            if (_wbsCanvas.ReadOnly)
            {
                text += " (Read Only)";
            }
            if (!string.IsNullOrEmpty(path))
                UpdateRecentFiles(_wbsCanvas.WorkBreakdownStructure.Title, path);
            Text = text;
        }

        private void quitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Close();
        }

        private void printToolStripMenuItem_Click(object sender, EventArgs e)
        {
            _wbsCanvas.Print();
        }

        private void loadXMLToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (!QueryUserDirtyDocument())
                return;
            DialogResult res = _openFileDialog.ShowDialog();
            if (res == DialogResult.OK)
            {
                if (_wbsCanvas.LoadXml(_openFileDialog.FileName))
                {
                    SetFileNameInTitle();
                }
            }
        }

        private void saveXMLToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Save();
        }

        private bool Save()
        {
            if (_wbsCanvas.Root.IsPublished)
            {
                if (!_wbsCanvas.TfsClient.IsConnected)
                {
                    MessageBox.Show("This Work Breakdown Structure definition has been published to Work Item #" + _wbsCanvas.Root.WorkItemId + "\n\n" +
                        "In order to save, you must be connected to Team System.", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    return false;
                }
                try
                {
                    Cursor.Current = Cursors.WaitCursor;
                    return _wbsCanvas.SaveRootToWorkItem();
                }
                finally
                {
                    Cursor.Current = Cursors.Default;
                }
            }
            else
            {
                if (string.IsNullOrEmpty(_wbsCanvas.WorkBreakdownStructure.FileName))
                {
                    return SaveAs();
                }
                else
                {
                    return _wbsCanvas.SaveXml(_wbsCanvas.WorkBreakdownStructure.FileName);
                }
            }
        }

        private void saveXMLAsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            SaveAs();
        }

        private bool SaveAs()
        {
            DialogResult res = _saveFileDialog.ShowDialog();
            if (res == DialogResult.OK)
            {
                if (_wbsCanvas.SaveXml(_saveFileDialog.FileName))
                {
                    SetFileNameInTitle();
                    return true;
                }
            }
            return false;
        }

        private void _wbsCanvas_AssigneeListChanged(object sender, EventArgs e)
        {
            string person = _wbsCanvas.Settings.HighlightName;
            _personHighlightComboBox.Items.Clear();
            _personHighlightComboBox.Items.Add("(no highlight)");
            _personHighlightComboBox.Items.AddRange(_wbsCanvas.GetAssignees());
            bool refresh = false;
            if (person != null &&
                _personHighlightComboBox.Items.Contains(person))
            {
                _personHighlightComboBox.Text = person;
            }
            else
            {
                refresh = (person != null);
                _personHighlightComboBox.Text = "(no highlight)";
                person = null;
            }
            _wbsCanvas.Settings.HighlightName = person;
            if (refresh)
                _wbsCanvas.Refresh();
        }

        private void _personHighlightComboBox_TextChanged(object sender, EventArgs e)
        {
            string person = _personHighlightComboBox.Text;
            if (person != _wbsCanvas.Settings.HighlightName)
            {
                _wbsCanvas.Settings.HighlightName = person;
                _wbsCanvas.Refresh();
            }
        }

        private void _wbsCanvas_TfsConnectRequested(object sender, TfsConnectEventArgs e)
        {
            AutoConnectToTfs();
            e.HasHandledConnect = true;
        }

        private void _wbsCanvas_TfsSuccessfullyConnected(object sender, EventArgs e)
        {
            teamProjectComboBox.Items.Clear();
            string[] teamProjects = _wbsCanvas.TfsClient.GetTeamProjectNames();
            teamProjectComboBox.Items.AddRange(teamProjects);
            teamProjectComboBox.Enabled = true;
            publishToolStripMenuItem.Enabled = true;
            rePublishTitlesToolStripMenuItem.Enabled = true;
            refreshToolStripMenuItem.Enabled = true;
            workItemGridToolStripMenuItem.Enabled = true;
            _refreshStripButton.Enabled = true;
            loadFromWorkItemToolStripMenuItem.Enabled = true;
            loadFromWorkItemToolStripMenuItem2.Enabled = true;
            browseForWorkItemToolStripMenuItem.Enabled = true;
            highlightIterationButton.Enabled = true;

            if (!string.IsNullOrEmpty(WbsEditor.Properties.Settings.Default.TeamProject))
            {
                string teamProject = WbsEditor.Properties.Settings.Default.TeamProject;
                teamProjectComboBox.Text = teamProject;
                _wbsCanvas.TfsClient.TeamProject = teamProject;
            }
            LoadIterations();

            if (!string.IsNullOrEmpty(WbsEditor.Properties.Settings.Default.Iteration))
            {
                string iteration = WbsEditor.Properties.Settings.Default.Iteration;
                _iterationComboBox.Text = iteration;
                _wbsCanvas.TfsClient.Iteration = iteration;
            }

            workItemTypeCombo.Items.Clear();
            string[] workItemTypes = _wbsCanvas.TfsClient.GetWorkItemTypes();
            workItemTypeCombo.Items.AddRange(workItemTypes);
        }

        private void LoadIterations()
        {
            if (string.IsNullOrEmpty(_wbsCanvas.TfsClient.TeamProject))
            {
                _iterationComboBox.Items.Clear();
                _iterationComboBox.Enabled = false;
            }
            else
            {
                _iterationComboBox.Items.Clear();
                string[] iterations = _wbsCanvas.TfsClient.GetTeamProjectIterations();
                _iterationComboBox.Items.AddRange(iterations);
                _iterationComboBox.Enabled = true;
            }
        }

        private void _teamProjectComboBox_TextChanged(object sender, EventArgs e)
        {
            if (teamProjectComboBox.Text != _wbsCanvas.TfsClient.TeamProject)
            {
                _wbsCanvas.TfsClient.TeamProject = teamProjectComboBox.Text;
                LoadIterations();
            }
        }

        private void _wbsCanvas_WbsNodeSelectionChanged(object sender, WbsEventArgs e)
        {
            bool isNodeSelected = (e.WbsNode != null);
            bool isNodePublished = false;
            bool isRoot = isNodeSelected && (e.WbsNode.IsRoot);
            // Team menu
            if (_wbsCanvas.TfsClient.IsConnected)
            {
                bool canPublish = false;
                bool canRefresh = false;
                bool canOpen = false;
                bool canAttach = isNodeSelected;
                if (isNodeSelected)
                {
                    isNodePublished = e.WbsNode.IsPublished;
                    canPublish = !isNodePublished;
                    canRefresh = isNodePublished;
                    canOpen = isNodePublished;
                }
                publishNodeToolStripMenuItem.Enabled = canPublish;
                refreshNodeToolStripMenuItem.Enabled = canRefresh;
                openWorkItemToolStripMenuItem.Enabled = canOpen;
                attachToWorkItemToolStripMenuItem.Enabled = canAttach;
            }
            else
            {
                publishNodeToolStripMenuItem.Enabled = false;
                refreshNodeToolStripMenuItem.Enabled = false;
                openWorkItemToolStripMenuItem.Enabled = false;
                attachToWorkItemToolStripMenuItem.Enabled = false;
            }

            // Edit menu
            cutToolStripMenuItem.Enabled = isNodeSelected && !_wbsCanvas.SelectedNode.IsRoot;
            copyToolStripMenuItem.Enabled = isNodeSelected;
            copyWorkItemIDToolStripMenuItem.Enabled = isNodeSelected && isNodePublished;
            bool enablePaste = isNodeSelected && WbsExporter.HasClipboardWbsNode();
            pasteToolStripMenuItem.Enabled = enablePaste;
            bool isNodeLeaf = false;
            if (_wbsCanvas.SelectedNode != null)
            {
                isNodeLeaf = _wbsCanvas.SelectedNode.IsLeaf;
            }
            pasteAssigneeToolStripMenuItem.Enabled = enablePaste && !isNodePublished;
            pasteEstimationToolStripMenuItem.Enabled = enablePaste && !isNodePublished && isNodeLeaf;
            pasteIterationToolStripMenuItem.Enabled = isNodeSelected && !isRoot && _wbsCanvas.TfsClient.IsConnected;

            // Status panel
            string statusString = "Idle";
            if (e.WbsNode != null
                && _wbsCanvas.Settings.CheckPlausis)
            {
                if (!string.IsNullOrEmpty(e.WbsNode.PlausiText))
                    statusString = "Warning: " + StripPlausiText(e.WbsNode.PlausiText);
            }
            statusLabel.Text = statusString;
        }

        private string StripPlausiText(string p)
        {
            if (p.StartsWith("!"))
                return p.Substring(1);
            return p;
        }

        private void connectToTeamFoundationServerToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ManuallyConnectToTfs();
        }

        private void AutoConnectToTfs()
        {
            this.ConnectToTfs(true);
        }
        private void ManuallyConnectToTfs()
        {
            this.ConnectToTfs(false);
        }
        private void ConnectToTfs(bool autoconnect)
        {
            Cursor current = Cursor.Current;
            Cursor.Current = Cursors.WaitCursor;

            if (autoconnect && !String.Equals("http://", Settings.Default.TfsUrl))
            {
                try
                {
                    _wbsCanvas.TfsClient.Connect(Settings.Default.TfsUrl, !Settings.Default.CustomAuthentication,
                    Settings.Default.UserName, Settings.Default.Domain, Settings.Default.Password);
                }
                catch (Exception)
                {
                }
            }
            if (!autoconnect || !_wbsCanvas.TfsClient.IsConnected)
            {
                try
                {
                    EnterTfsUrlForm enterUrlForm = new EnterTfsUrlForm();
                    enterUrlForm.UseWindowsAuthentication = !WbsEditor.Properties.Settings.Default.CustomAuthentication;

                    if (DialogResult.OK == enterUrlForm.ShowDialog(this))
                    {
                        WbsEditor.Properties.Settings.Default.CustomAuthentication = !enterUrlForm.UseWindowsAuthentication;

                        _wbsCanvas.TfsClient.Connect(Settings.Default.TfsUrl, !Settings.Default.CustomAuthentication, Settings.Default.UserName, Settings.Default.Domain, Settings.Default.Password);
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show("An error occurred while connecting to the Team Foundation Server:\n\n" + ex.Message,
                        "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }

            if (_wbsCanvas.TfsClient.IsConnected)
            {
                //MessageBox.Show("Successfully connected to Team Foundation Server.", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
                connectToTeamFoundationServerToolStripMenuItem.Enabled = false;
            }

            Cursor.Current = current;
        }

        private void publishNodeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            _wbsCanvas.PublishWorkItem(_wbsCanvas.SelectedNode);
        }

        private void refreshNodeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            _wbsCanvas.RefreshWorkItem(_wbsCanvas.SelectedNode);
        }

        private void openWorkItemToolStripMenuItem_Click(object sender, EventArgs e)
        {
            _wbsCanvas.OpenWorkItem(_wbsCanvas.SelectedNode);
        }

        private void _wbsCanvas_LengthyOperationStarted(object sender, WbsLengthyOperationEventArgs e)
        {
            statusLabel.Text = "Working...";
            statusProgressBar.Minimum = 0;
            statusProgressBar.Maximum = e.Count;
            statusProgressBar.Value = 0;
            statusProgressBar.Visible = true;
        }

        private void _wbsCanvas_LengthyOperationTick(object sender, WbsLengthyOperationEventArgs e)
        {
            statusProgressBar.Value = e.Count;
        }

        private void _wbsCanvas_LengthyOperationFinished(object sender, WbsLengthyOperationEventArgs e)
        {
            statusLabel.Text = "Idle";
            statusProgressBar.Visible = false;
        }

        private void refreshToolStripMenuItem_Click(object sender, EventArgs e)
        {
            _wbsCanvas.RefreshAll();
        }

        private void publishToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(teamProjectComboBox.Text))
            {
                MessageBox.Show("Please select a Team Project to create the tasks in first.", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }
            _wbsCanvas.PublishAll();
        }

        private void attachToWorkItemToolStripMenuItem_Click(object sender, EventArgs e)
        {
            _wbsCanvas.AttachToWorkItem(_wbsCanvas.SelectedNode);
        }

        private void loadWbsFromWorkItemToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (!QueryUserDirtyDocument())
                return;
            _wbsCanvas.LoadFromWorkItem(-1);
            SetFileNameInTitle();
        }

        private void _iterationComboBox_TextChanged(object sender, EventArgs e)
        {
            _wbsCanvas.TfsClient.Iteration = _iterationComboBox.Text;
            if (highlightIterationButton.Checked)
                _wbsCanvas.Refresh();
        }

        private void _wbsCanvas_WbsRootWasPublished(object sender, EventArgs e)
        {
            SetFileNameInTitle();
        }

        private void aboutWbsEditorToolStripMenuItem_Click(object sender, EventArgs e)
        {
            MessageBox.Show(this,
                CAPTION + "\n\n" +
                "(c) 2010-2011 Haufe-Lexware GmbH & Co. KG\n\n" +
                "Author: Martin Danielsson\n" +
                "E-Mail: martin.danielsson@lexware.de",
                "About WbsEditor",
                MessageBoxButtons.OK,
                MessageBoxIcon.Information);
        }

        private void propertiesToolStripMenuItem_Click(object sender, EventArgs e)
        {
            _wbsCanvas.EditWbsProperties();
        }

        private void _wbsCanvas_LayoutChanged(object sender, EventArgs e)
        {
            bool smallChecked = false;
            bool normalChecked = false;
            bool largeChecked = false;
            if (_wbsCanvas.Settings.Layout == WbsSettings.LayoutSize.Small)
                smallChecked = true;
            else if (_wbsCanvas.Settings.Layout == WbsSettings.LayoutSize.Normal)
                normalChecked = true;
            else
                largeChecked = true;
            smallToolStripMenuItem.Checked = smallChecked;
            normalToolStripMenuItem.Checked = normalChecked;
            largeToolStripMenuItem.Checked = largeChecked;
        }

        private void smallToolStripMenuItem_Click(object sender, EventArgs e)
        {
            _wbsCanvas.SetLayout(WbsSettings.LayoutSize.Small);
        }

        private void normalToolStripMenuItem_Click(object sender, EventArgs e)
        {
            _wbsCanvas.SetLayout(WbsSettings.LayoutSize.Normal);
        }

        private void largeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            _wbsCanvas.SetLayout(WbsSettings.LayoutSize.Large);
        }

        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (e.CloseReason != CloseReason.WindowsShutDown)
            {
                if (!QueryUserDirtyDocument())
                    e.Cancel = true;
            }
            StringCollection recentFiles = WbsEditor.Properties.Settings.Default.RecentWbs;
            if (null == recentFiles)
            {
                recentFiles = new StringCollection();
                WbsEditor.Properties.Settings.Default.RecentWbs = recentFiles;
            }
            recentFiles.Clear();
            var items = _recentWbsMenuItem.DropDownItems;
            int maxRecentCount = items.Count;

            for (int i = 0; i < maxRecentCount; ++i)
            {
                if (items[i].Tag != null)
                {
                    recentFiles.Add((string)items[i].Tag);
                }
            }

            if (_wbsCanvas.TfsClient.IsConnected)
            {
                WbsEditor.Properties.Settings.Default.TeamProject = _wbsCanvas.TfsClient.TeamProject;
                WbsEditor.Properties.Settings.Default.Iteration = _wbsCanvas.TfsClient.Iteration;
            }

            WbsEditor.Properties.Settings.Default.EstimationPercentage = _wbsCanvas.EstimationPercentageDefault;
            WbsEditor.Properties.Settings.Default.Save();
        }

        // returns true if if is ok to continue
        private bool QueryUserDirtyDocument()
        {
            if (_wbsCanvas.WorkBreakdownStructure.IsDirty)
            {
                DialogResult res = MessageBox.Show("There were changes to the Work Breakdown Structure.\n\nDo you want to save them?", "Confirm",
                    MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);
                if (res == DialogResult.Cancel)
                    return false;
                if (res == DialogResult.Yes)
                    return Save();
                return true;
            }
            else
            {
                return true;
            }
        }

        private void _wbsCanvas_DirtyFlagSet(object sender, EventArgs e)
        {
            SetFileNameInTitle();
        }

        private void _wbsCanvas_DirtyFlagReset(object sender, EventArgs e)
        {
            SetFileNameInTitle();
        }

        private void showWorkloadInformationToolStripMenuItem_Click(object sender, EventArgs e)
        {
            _wbsCanvas.ShowWorkloadInformation(_wbsCanvas.Root);
        }

        private void OnOpenRecentFileClick(object sender, EventArgs e)
        {
            if (!QueryUserDirtyDocument())
                return;
            ToolStripMenuItem item = (ToolStripMenuItem)sender;
            string title = "";
            string path = "";
            if (null == item.Tag)
                return;
            string tag = (string)item.Tag;
            if (SplitLocation(tag, ref title, ref path))
            {
                if (path.StartsWith("#"))
                {
                    int workItemId = 0;
                    if (int.TryParse(path.Substring(1), out workItemId))
                    {
                        _wbsCanvas.LoadFromWorkItem(workItemId);
                    }
                    else
                    {
                        MessageBox.Show("Unknown type of ID: " + path, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
                else
                {
                    _wbsCanvas.LoadXml(path);
                }
            }
        }

        private void exportAsImageToolStripMenuItem_Click(object sender, EventArgs e)
        {
            DialogResult res = _savePngDialog.ShowDialog();
            if (DialogResult.OK == res)
            {
                if (_wbsCanvas.ExportAsImage(_savePngDialog.FileName))
                {
                    System.Diagnostics.Process.Start(System.IO.Path.GetDirectoryName(_savePngDialog.FileName));
                }
            }
        }

        private void rePublishTitlesToolStripMenuItem_Click(object sender, EventArgs e)
        {
            _wbsCanvas.RePublishTitles();
        }

        private void browseForWorkItemToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (!_wbsCanvas.CheckTfsConnectState())
                return;

            WbsWorkItemSelectionForm form = new WbsWorkItemSelectionForm();
            form.TfsClient = _wbsCanvas.TfsClient;
            if (DialogResult.OK == form.ShowDialog())
            {
                if (!QueryUserDirtyDocument())
                    return;
                int id = form.WorkItemId;
                if (id > 0)
                {
                    _wbsCanvas.LoadFromWorkItem(id);
                }
            }
            if (_wbsCanvas.TfsClient.TeamProject != teamProjectComboBox.Text)
            {
                teamProjectComboBox.Text = _wbsCanvas.TfsClient.TeamProject;
                LoadIterations();
            }
        }

        private void expandAllNodesToolStripMenuItem_Click(object sender, EventArgs e)
        {
            _wbsCanvas.ExpandTree();
        }

        private void collapseFromLevel2ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            _wbsCanvas.CollapseFromLevel(2);
        }

        private void collapseFromLevel3ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            _wbsCanvas.CollapseFromLevel(3);
        }

        private void collapseFromLevel4ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            _wbsCanvas.CollapseFromLevel(4);
        }

        private void preferencesToolStripMenuItem_Click(object sender, EventArgs e)
        {
            PreferencesDialog prefs = new PreferencesDialog();
            prefs.FontFamily = WbsEditor.Properties.Settings.Default.Font;
            prefs.TfsClient = _wbsCanvas.TfsClient;
            prefs.EnableTfsTab = _wbsCanvas.TfsClient.IsConnected;
            prefs.ShowDialog(this);

            WbsEditor.Properties.Settings.Default.Font = prefs.FontFamily;
            WbsEditor.Properties.Settings.Default.RefreshAtLoad = (int)prefs.RefreshAtLoad;

            ReadUserSettings();
            _wbsCanvas.RefreshPlausis();
        }

        private void exportToMSProjectToolStripMenuItem_Click(object sender, EventArgs e)
        {
            DialogResult res = _saveMpxDialog.ShowDialog();
            if (DialogResult.OK == res)
            {
                WbsExporter.ExportWbsAsMpx(_wbsCanvas.WorkBreakdownStructure, _saveMpxDialog.FileName);
                //WbsExporter.ExportWbsAsProject2007Xml(_wbsCanvas.WorkBreakdownStructure, _saveMpxDialog.FileName);
            }
        }

        private void hideShortcutHelpWindowToolStripMenuItem_Click(object sender, EventArgs e)
        {
            WbsEditor.Properties.Settings.Default.HideShortcutWindow = hideShortcutHelpWindowToolStripMenuItem.Checked;
        }

        private void exportWMFToClipboardToolStripMenuItem_Click(object sender, EventArgs e)
        {
            DialogResult res = _saveEmfDialog.ShowDialog();
            if (DialogResult.OK == res)
            {
                if (_wbsCanvas.ExportAsEmf(_saveEmfDialog.FileName))
                {
                    System.Diagnostics.Process.Start(System.IO.Path.GetDirectoryName(_saveEmfDialog.FileName));
                }
            }
        }

        private void generatePersonalizedWBSToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (!QueryUserDirtyDocument())
                return;
            _wbsCanvas.GeneratePersonalizedWbs();
        }

        private void generateIterationWorkloadChartToolStripMenuItem_Click(object sender, EventArgs e)
        {
            _wbsCanvas.GenerateWorkloadChart();
        }

        private void _findStripButton_Click(object sender, EventArgs e)
        {
            if (_findStripButton.Checked && !string.IsNullOrEmpty(_findStringEdit.Text))
            {
                _wbsCanvas.Settings.FindString = _findStringEdit.Text;
            }
            else
            {
                _wbsCanvas.Settings.FindString = null;
            }
            _wbsCanvas.Refresh();
        }

        private void _findStringEdit_TextChanged(object sender, EventArgs e)
        {
            _findStripButton.Checked = true;
            _wbsCanvas.Settings.FindString = _findStringEdit.Text;
            _findStripButton_Click(sender, new EventArgs());
        }

        private void _findStringEdit_KeyPress(object sender, KeyPressEventArgs e)
        {
            //if (e.Key == Keys.Return
            //    || e.Key == Keys.Enter)
            //{
            //    MessageBox.Show("Woo");
            //}
        }

        private void _findStringEdit_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Return
                || e.KeyCode == Keys.Enter)
            {
                if (_wbsCanvas.SelectFirstHighlightedNode())
                {
                    _wbsCanvas.Refresh();
                    _wbsCanvas.Focus();
                }
            }
        }

        private void _wbsCanvas_RequestFindUI(object sender, EventArgs e)
        {
            _findStringEdit.SelectAll();
            _findStringEdit.Focus();
        }

        private void newToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (!QueryUserDirtyDocument())
                return;
            _wbsCanvas.New();
        }

        private void cutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            _wbsCanvas.Cut();
        }

        private void copyToolStripMenuItem_Click(object sender, EventArgs e)
        {
            _wbsCanvas.Copy();
        }

        private void pasteToolStripMenuItem_Click(object sender, EventArgs e)
        {
            _wbsCanvas.Paste();
        }

        private void onlineDocumentationToolStripMenuItem_Click(object sender, EventArgs e)
        {
            System.Diagnostics.Process.Start("http://wbseditor.codeplex.com/documentation");
        }

        private void pasteAssigneeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            _wbsCanvas.PasteAssignee();
        }

        private void pasteEstimationToolStripMenuItem_Click(object sender, EventArgs e)
        {
            _wbsCanvas.PasteEstimation();
        }

        private void workItemGridToolStripMenuItem_Click(object sender, EventArgs e)
        {
            _wbsCanvas.DisplayWorkItemGrid();
        }

        private void _wbsCanvas_ZoomChanged(object sender, EventArgs e)
        {
            this._zoomComboBox.Text = this._wbsCanvas.Zoom.ToString("#0 %");
        }
        private void _zoomComboBox_TextChanged(object sender, EventArgs e)
        {
            string zoomValue = Regex.Match(this._zoomComboBox.Text, @"^(?<value>[0-9]+)\ ?\%?$").Groups["value"].Value;
            float zoom;
            if (float.TryParse(zoomValue, out zoom))
                this._wbsCanvas.Zoom = zoom / 100.0f;
        }

        private void workItemTypeCombo_TextChanged(object sender, EventArgs e)
        {
            _wbsCanvas.CurrentWorkItemType = workItemTypeCombo.Text;
        }

        private void pasteIterationToolStripMenuItem_Click(object sender, EventArgs e)
        {
            _wbsCanvas.CopyIterationToSelectedNode();
        }

        private void highlightIterationButton_Click(object sender, EventArgs e)
        {
            _wbsCanvas.Settings.HighlightCurrentIteration = highlightIterationButton.Checked;
            _wbsCanvas.Refresh();
        }

        private void iterationDashboardToolStripMenuItem_Click(object sender, EventArgs e)
        {
            _wbsCanvas.DisplayIterationDashboard();
        }

        private void registerWbseditProtocolHandlerToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ProtocolSetup.Register();
        }

        private void unregisterWbseditProtocolHandlerToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ProtocolSetup.Unregister();
        }

        private void helpToolStripMenuItem_DropDownOpening(object sender, EventArgs e)
        {
            registerWbseditProtocolHandlerToolStripMenuItem.Enabled = !ProtocolSetup.IsProtocolRegistered;
            unregisterWbseditProtocolHandlerToolStripMenuItem.Enabled = ProtocolSetup.IsProtocolRegistered;
        }

        private void _wbsCanvas_EditModeEntered(object sender, EventArgs e)
        {
            cutToolStripMenuItem.Enabled = false;
            copyToolStripMenuItem.Enabled = false;
            copyWorkItemIDToolStripMenuItem.Enabled = false;
            pasteToolStripMenuItem.Enabled = false;
        }

        private void _wbsCanvas_EditModeExited(object sender, EventArgs e)
        {
            _wbsCanvas_WbsNodeSelectionChanged(sender, new WbsEventArgs(_wbsCanvas.SelectedNode));
        }

        private void copyWorkItemIDToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (null == _wbsCanvas.SelectedNode)
                return;

            Clipboard.SetText(_wbsCanvas.SelectedNode.WorkItemId.ToString());
        }
    }
}